#define _CRT_SECURE_NO_WARNINGS 1
/*
 * @Author: xiaohao
 * @Date: 2025-11-06 02:17:08
 * @LastEditors: xiaohao
 * @LastEditTime: 2025-11-06 19:33:31
 * @FilePath: /Project/ConcurrentMemoryPool/test/Benchmark.cpp
 * @Description:
 */
#include "ConcurrentMemoryPool/ConcurrentAlloc.h"

// ntimes：一轮申请和释放内存的次数；rounds：轮次
void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
    std::vector<std::thread> vthread(nworks);
    std::atomic<size_t> malloc_costtime(0); // 修正：直接构造初始化
    std::atomic<size_t> free_costtime(0);

    for (size_t k = 0; k < nworks; ++k)
    {
        vthread[k] = std::thread([&]() // 移除未使用的k参数
                                 {
                std::vector<void*> v;
                v.reserve(ntimes);

                for (size_t j = 0; j < rounds; ++j)
                {
                    size_t begin1 = clock();
                    for (size_t i = 0; i < ntimes; i++)
                    {
                        //v.push_back(malloc(16));
                        v.push_back(malloc((16 + i) % 8192 + 1));  // 随机大小测试
                    }
                    size_t end1 = clock();

                    size_t begin2 = clock();
                    for (size_t i = 0; i < ntimes; i++)
                    {
                        free(v[i]);
                    }
                    size_t end2 = clock();
                    v.clear();

                    malloc_costtime += (end1 - begin1);  // 原子操作累加，线程安全
                    free_costtime += (end2 - begin2);
                } });
    }

    for (auto &t : vthread)
    {
        t.join();
    }

    // 使用load()获取原子变量值，%lu匹配size_t
    printf("%lu个线程并发执行%lu轮次，每轮次malloc %lu次: 花费：%lu ms\n",
           nworks, rounds, ntimes, malloc_costtime.load());

    printf("%lu个线程并发执行%lu轮次，每轮次free %lu次: 花费：%lu ms\n",
           nworks, rounds, ntimes, free_costtime.load());

    printf("%lu个线程并发malloc&free %lu次，总计花费：%lu ms\n",
           nworks, nworks * rounds * ntimes,
           malloc_costtime.load() + free_costtime.load());
}

// 测试并发内存池的性能
void BenchmarkConcurrentMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
    std::vector<std::thread> vthread(nworks);
    std::atomic<size_t> malloc_costtime(0); // 修正：直接构造初始化
    std::atomic<size_t> free_costtime(0);

    for (size_t k = 0; k < nworks; ++k)
    {
        vthread[k] = std::thread([&]()
                                 {
                std::vector<void*> v;
                v.reserve(ntimes);

                for (size_t j = 0; j < rounds; ++j)
                {
                    size_t begin1 = clock();
                    for (size_t i = 0; i < ntimes; i++)
                    {
                        //v.push_back(ConcurrentAlloc(16));
                        v.push_back(ConcurrentAlloc((16 + i) % 8192 + 1));  // 调用自定义内存池
                    }
                    size_t end1 = clock();

                    size_t begin2 = clock();
                    for (size_t i = 0; i < ntimes; i++)
                    {
                        ConcurrentFree(v[i]);
                    }
                    size_t end2 = clock();
                    v.clear();

                    malloc_costtime += (end1 - begin1);
                    free_costtime += (end2 - begin2);
                } });
    }

    for (auto &t : vthread)
    {
        t.join();
    }

    // 修使用load()获取原子变量值，%lu匹配size_t
    printf("%lu个线程并发执行%lu轮次，每轮次concurrent alloc %lu次: 花费：%lu ms\n",
           nworks, rounds, ntimes, malloc_costtime.load());

    printf("%lu个线程并发执行%lu轮次，每轮次concurrent dealloc %lu次: 花费：%lu ms\n",
           nworks, rounds, ntimes, free_costtime.load());

    printf("%lu个线程并发concurrent alloc&dealloc %lu次，总计花费：%lu ms\n",
           nworks, nworks * rounds * ntimes,
           malloc_costtime.load() + free_costtime.load());
}

int main()
{
    size_t n = 10000; // 每轮次操作次数
    std::cout << "==========================================================" << std::endl;
    BenchmarkConcurrentMalloc(n, 4, 10); // 测试自定义并发内存池
    std::cout << std::endl
              << std::endl;

    BenchmarkMalloc(n, 4, 10); // 测试系统malloc/free
    std::cout << "==========================================================" << std::endl;

    return 0;
}